package com.qianfeng.websocket;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.PongMessage;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/*
 *@Description:
 *@author:刘哥
 *@Date:86180 2022/9/13 16:37
 * websocket是有状态的协议,能更好的节省服务器资源和带宽，并且能够更实时地进行通讯。
 * WebSocket使得客户端和服务器之间的数据交换变得更加简单，允许服务端主动向客户端推送数据。在WebSocket API中，
 * 浏览器和服务器只需要完成一次握手，两者之间就直接可以创建持久性的连接，并进行双向数据传输。
 */
@Component
@EnableWebSocket//开启websocket
public class TestWebscoket extends TextWebSocketHandler {
    private ObjectMapper objectMapper;
    @Autowired
    public void setObjectMapper(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    private Map<String,WebSocketSession> allClients=new ConcurrentHashMap<>();

    /**
     * //    确认连接成功之后执行
     * @param session 建立连接成功的回话
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        String path = session.getUri().getPath();
        System.out.println("path = " + path);
//        约定好路径的最后是用户名,
        String userName = path.substring(path.lastIndexOf("/") + 1);
//        把用户名存到会话中方便后面取出
        session.getAttributes().put("user",userName);
//        保存会话
        System.out.println(session);
        allClients.put(userName,session);
    }
//   处理文本信息
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
//        session.sendMessage(new TextMessage( "这是回复的消息"));
        String payload = message.getPayload();
        System.out.println(payload);
//        将接收到的数据转为map集合
        Map map = objectMapper.readValue(payload, Map.class);
        String toUser = (String) map.get("toUser");
        String msg = (String) map.get("msg");
//        获取对方的会话
        WebSocketSession toSession= allClients.get(toUser);
//        从会话中取出用户名
        Object userName = session.getAttributes().get("user");
//        toSession.isOpen()判断会话是不是已经连接成功
        if (msg!=null && toSession.isOpen()){
            toSession.sendMessage(new TextMessage("收到来自于" + userName + "的消息,内容是:" + msg));
        }else{
            session.sendMessage(new TextMessage("对方不在线"));
        }

    }
//   长链接一直访问返回信息
    @Override
    protected void handlePongMessage(WebSocketSession session, PongMessage message) throws Exception {

    }
// 当发生异常时执行
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {

    }
// 关闭连接成功之后
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {

    }
}
